package cn.memset.code.jcf;

import java.util.*;

public class MapExample {
    public static void main(String[] args) {
        mapMerge();
    }

    public static void mapForEach() {
        Map<String, String> cityMap = new HashMap<>();
        cityMap.put("Guangdong", "Guangzhou");
        cityMap.put("Zhejiang", "Hangzhou");
        cityMap.put("Jiangsu", "Nanjing");

        cityMap.forEach((key, value) -> {
            System.out.println(String.format("%s 的省府是 %s", key, value));
        });
    }

    public static void mapReplaceAll() {
        Map<String, String> cityMap = new HashMap<>();
        cityMap.put("Guangdong", "Guangzhou");
        cityMap.put("Zhejiang", "Hangzhou");
        cityMap.put("Jiangsu", "Nanjing");

        // 将省府的拼音转换为大写
        cityMap.replaceAll((key, value) -> {
            return value.toUpperCase();
        });

        cityMap.forEach((key, value) -> {
            System.out.println(String.format("%s 的省府大写是 %s", key, value));
        });
    }

    public static void mapCompute() {
        Map<String, String> cityMap = new HashMap<>();
        cityMap.put("Guangdong", "null");
        cityMap.put("Zhejiang", "Hangzhou");
        cityMap.put("Jiangsu", "null");

        // 稍显复杂的语句，先调用 forEach 遍历 cityMap 中的键，然后根据原有的键值对计算新的值
        Set<String> keys = new HashSet<>(cityMap.keySet());
        keys.forEach(key -> {
            cityMap.compute(key, (k, v) -> {
                // 如果是 Guangdong，则返回 Guangzhou
                if ("Guangdong".equals(k)) {
                    return "Guangzhou";
                }

                // 如果旧的键值对中，值是字符串 "null" ，则返回 null。
                // 这意味着 cityMap 会删除对应的key
                if ("null".equals(v)) {
                    return null;
                }

                // 否则，返回原来的 value 值
                return v;
            });
        });

        cityMap.forEach((key, value) -> {
            System.out.println(String.format("%s 的省会是 %s", key, value));
        });
    }

    public static void mapComputeIfAbsent() {
        Map<String, Integer> staffMap = new HashMap<>();
        staffMap.put("Lilei", 24);
        staffMap.put("Hanmeimei", 22);
        staffMap.put("Liming", 24);
        staffMap.put("Jim", 22);
        staffMap.put("David", 24);

        Map<Integer, List<String>> staffInvertMap = new HashMap<>();
        staffMap.forEach((key, value) -> {
            // 以年龄为键，构建一个新的Map
            // 以 22 岁为例：
            // 如果 staffInvertMap 之前不存在 22 岁对应的映射关系，
            // 则新建一个 "年龄 -> ArrayList<String>" 的映射，并且把新建的 ArrayList 返回。
            // 如果 staffInvertMap 已经存在 22 岁对应的映射关系了，则将已存在的 ArrayList 返回。
            List<String> nameList = staffInvertMap.computeIfAbsent(value, age -> {
                // 对于同一个 age，这句代码只会执行一次
                return new ArrayList<>();
            });

            nameList.add(key);
        });

        System.out.println(staffInvertMap);
    }

    public static void mapMerge() {
        Map<String, String> staffMap = new HashMap<>();
        staffMap.put("Lilei", "性别男 ");

        // 等价于 staffMap.merge("Lilei", "年龄24", String::concat)
        // oldValue 即之前添加的值 “性别男 ”，value 即merge函数的第二个参数 “年龄24”
        staffMap.merge("Lilei", "年龄24", (oldValue, value) -> oldValue.concat(value));
        staffMap.merge("Hanmeimei", "年龄22", String::concat);

        System.out.println(staffMap);
    }
}
